const Router = require('koa-router');
const { pool } = require('../config/db');
const { 
  encryptPassword, 
  verifyPassword, 
  generateToken, 
  authMiddleware, 
  refreshToken,
  getTokenFromRequest
} = require('../utils/auth');
const { v4: uuidv4 } = require('uuid');

const router = new Router({
  prefix: '/user'
});

/**
 * 用户注册
 * POST /user/register
 */
router.post('/register', async (ctx) => {
  const { username, password } = ctx.request.body;
  
  // 参数校验
  if (!username || !password) {
    ctx.status = 400;
    ctx.body = {
      errCode: 'PARAM_IS_NULL',
      errMsg: '用户名或密码不能为空',
      data: null
    };
    return;
  }
  
  try {
    // 检查用户名是否已存在
    const [existingUsers] = await pool.execute(
      'SELECT * FROM users WHERE username = ?',
      [username]
    );
    
    if (existingUsers.length > 0) {
      ctx.status = 400;
      ctx.body = {
        errCode: 'USER_ALREADY_EXISTS',
        errMsg: '用户名已存在',
        data: null
      };
      return;
    }
    
    // 加密密码
    const { hash, salt } = encryptPassword(password);
    
    // 生成UUID作为用户ID
    const userId = uuidv4();
    
    // 记录当前时间
    const now = Date.now();
    
    // 创建用户
    await pool.execute(
      'INSERT INTO users (id, username, password, salt, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?)',
      [userId, username, hash, salt, now, now]
    );
    
    // 生成token
    const token = generateToken({ userId });
    
    ctx.body = {
      errCode: 0,
      errMsg: '注册成功',
      data: {
        username,
        token
      }
    };
  } catch (error) {
    console.error('注册失败', error);
    ctx.status = 500;
    ctx.body = {
      errCode: 'REGISTER_FAILED',
      errMsg: '注册失败: ' + error.message,
      data: null
    };
  }
});

/**
 * 用户登录
 * POST /user/login
 */
router.post('/login', async (ctx) => {
  const { username, password } = ctx.request.body;
  
  // 参数校验
  if (!username || !password) {
    ctx.status = 400;
    ctx.body = {
      code: 400,
      message: '用户名和密码不能为空'
    };
    return;
  }
  
  try {
    // 查询用户
    const [users] = await pool.execute(
      'SELECT * FROM users WHERE username = ?',
      [username]
    );
    
    if (users.length === 0) {
      ctx.status = 404;
      ctx.body = {
        code: 404,
        message: '用户不存在'
      };
      return;
    }
    
    const user = users[0];
    
    // 验证密码
    const isPasswordValid = verifyPassword(password, user.password, user.salt);
    
    if (!isPasswordValid) {
      ctx.status = 401;
      ctx.body = {
        code: 401,
        message: '密码错误'
      };
      return;
    }
    
    // 生成token
    const token = generateToken({
      userId: user.id
    });
    
    // 更新最后登录时间
    await pool.execute(
      'UPDATE users SET last_login_time = ? WHERE id = ?',
      [new Date(), user.id]
    );
    
    ctx.body = {
      code: 200,
      message: '登录成功',
      data: {
        token,
        userId: user.id,
        username: user.username
      }
    };
  } catch (error) {
    console.error('登录失败', error);
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: '登录失败',
      error: error.message
    };
  }
});

/**
 * 获取用户信息
 * POST /user/getUserInfo
 */
router.post('/getUserInfo', authMiddleware, async (ctx) => {
  // 前置验证中间件已经处理了token验证和用户信息获取
  ctx.body = {
    code: 200,
    message: '获取成功',
    data: ctx.state.user
  };
});

/**
 * 更新用户信息
 * POST /user/updateUserInfo
 */
router.post('/updateUserInfo', authMiddleware, async (ctx) => {
  const params = ctx.request.body;
  
  // 不允许更新敏感信息
  delete params.password;
  delete params.salt;
  delete params.id;
  
  try {
    const userId = ctx.state.user.id;
    
    // 构建更新字段
    const updateFields = [];
    const updateValues = [];
    
    Object.keys(params).forEach(key => {
      updateFields.push(`${key} = ?`);
      updateValues.push(params[key]);
    });
    
    // 添加更新时间
    updateFields.push('update_time = ?');
    updateValues.push(new Date());
    
    // 添加用户ID
    updateValues.push(userId);
    
    // 如果没有要更新的字段，则直接返回成功
    if (updateFields.length === 1) { // 只有update_time
      ctx.body = {
        code: 200,
        message: '没有更新的字段'
      };
      return;
    }
    
    // 更新用户信息
    const [result] = await pool.execute(
      `UPDATE users SET ${updateFields.join(', ')} WHERE id = ?`,
      updateValues
    );
    
    ctx.body = {
      code: 200,
      message: '更新成功'
    };
  } catch (error) {
    console.error('更新用户信息失败', error);
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: '更新失败',
      error: error.message
    };
  }
});

/**
 * 修改密码
 * POST /user/changePassword
 */
router.post('/changePassword', authMiddleware, async (ctx) => {
  const { oldPassword, newPassword } = ctx.request.body;
  
  if (!oldPassword || !newPassword) {
    ctx.status = 400;
    ctx.body = {
      code: 400,
      message: '旧密码和新密码不能为空'
    };
    return;
  }
  
  try {
    const userId = ctx.state.user.id;
    
    // 查询用户完整信息（包含密码和盐值）
    const [users] = await pool.execute(
      'SELECT * FROM users WHERE id = ?',
      [userId]
    );
    
    if (users.length === 0) {
      ctx.status = 404;
      ctx.body = {
        code: 404,
        message: '用户不存在'
      };
      return;
    }
    
    const user = users[0];
    
    // 验证旧密码
    const isPasswordValid = verifyPassword(oldPassword, user.password, user.salt);
    
    if (!isPasswordValid) {
      ctx.status = 401;
      ctx.body = {
        code: 401,
        message: '旧密码错误'
      };
      return;
    }
    
    // 加密新密码
    const { hash, salt } = encryptPassword(newPassword);
    
    // 更新密码
    await pool.execute(
      'UPDATE users SET password = ?, salt = ?, update_time = ? WHERE id = ?',
      [hash, salt, new Date(), userId]
    );
    
    ctx.body = {
      code: 200,
      message: '密码修改成功'
    };
  } catch (error) {
    console.error('修改密码失败', error);
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: '修改密码失败',
      error: error.message
    };
  }
});

/**
 * 刷新Token
 * POST /user/refreshToken
 */
router.post('/refreshToken', async (ctx) => {
  // 从请求头获取token
  const token = getTokenFromRequest(ctx);
  
  if (!token) {
    ctx.status = 400;
    ctx.body = {
      code: 400,
      message: 'token不能为空，请在请求头中提供Authorization: Bearer <token>'
    };
    return;
  }
  
  // 刷新token
  const refreshResult = refreshToken(token);
  
  if (refreshResult.success) {
    ctx.body = {
      code: 200,
      message: refreshResult.message,
      data: {
        token: refreshResult.token
      }
    };
  } else {
    ctx.status = 401;
    ctx.body = {
      code: 401,
      message: refreshResult.message,
      error: refreshResult.error
    };
  }
});

module.exports = router; 